package main

import (
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
)

//定义客户端
type Client struct {
	ServerIp   string
	ServerPort int
	Name       string
	Conn       net.Conn
	Flag       int
}

//创建客户端
func NewClient(serverIp string, serverPort int) *Client {

	conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", serverIp, serverPort))

	if err != nil {
		fmt.Println("new dial error:", err)
		return nil
	}

	return &Client{
		ServerIp:   serverIp,
		ServerPort: serverPort,
		Conn:       conn,
		Flag:       999,
	}
}

//客户端处理业务
func (client *Client) Run() {
	for {
		for !client.Menu() {
		}

		switch client.Flag {
		case 1:
			client.PublicChat()
		case 2:
			client.PrivateChat()
		case 3:
			client.Rename()
		case 4:
			client.Query()
		case 5:
			client.OffLine()
		}
	}
}

//显示菜单
func (client *Client) Menu() bool {
	var flag string

	fmt.Println("1.公聊模式")
	fmt.Println("2.私聊模式")
	fmt.Println("3.修改用户名")
	fmt.Println("4.查询在线用户")
	fmt.Println("5.退出")

	fmt.Scanln(&flag)

	flagInt, err := strconv.Atoi(flag)
	if err == nil && flagInt > 0 && flagInt <= 4 {
		client.Flag = flagInt
		return true
	} else {
		fmt.Println("请输入合法模式")
		return false
	}
}

//更新用户名
func (client *Client) Rename() {
	fmt.Println(">>>>>请输入用户名")
	fmt.Scanln(&client.Name)

	msg := "rename " + client.Name
	client.SendMessage(msg)
}

//发送消息
func (client *Client) SendMessage(msg string) bool {
	if msg == "" {
		fmt.Println("消息内容为空")
		return false
	}
	_, error := client.Conn.Write([]byte(msg + "\n"))
	if error != nil {
		fmt.Println("conn write err:", error)
		return false
	} else {
		return true
	}
}

//接收消息
func (client *Client) ReadMessage() {
	io.Copy(os.Stdout, client.Conn)
}

//查询在线用户
func (client *Client) Query() {
	client.SendMessage("query")
}

//公聊
func (client *Client) PublicChat() {
	var msg string
	fmt.Println(">>>>>请输入聊天内容，exit退出")
	fmt.Scanln(&msg)
	for msg != "exit" {
		client.SendMessage(msg)
		fmt.Println(">>>>>请输入聊天内容，exit退出")
		fmt.Scanln(&msg)
	}
}

//私聊
func (client *Client) PrivateChat() {
	client.Query()
	var remoteName string
	fmt.Println(">>>>>请输入聊天对象用户名，exit退出")
	fmt.Scanln(&remoteName)
	for remoteName != "exit" {
		var msg string
		fmt.Println(">>>>>请输入聊天内容，exit退出")
		fmt.Scanln(&msg)
		for msg != "exit" {
			sendMsg := "to " + remoteName + " " + msg
			client.SendMessage(sendMsg)
			fmt.Println(">>>>>请输入聊天内容，exit退出")
			fmt.Scanln(&msg)
		}
		fmt.Println(">>>>>请输入聊天对象用户名，exit退出")
		fmt.Scanln(&remoteName)
	}
}

//下线
func (client *Client) OffLine() {
	client.Conn.Close()
}
